package me.flyray.bsin.infrastructure.biz.paychannel;

import lombok.extern.slf4j.Slf4j;
import me.flyray.bsin.payment.IPaymentService;
import me.flyray.bsin.payment.channel.wxpay.model.UnifyOrderReq;
import me.flyray.bsin.payment.channel.wxpay.model.RefundUnifyReq;
import me.flyray.bsin.payment.common.AbstractRes;
import me.flyray.bsin.payment.enums.ProfitSharingModeEnum;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Map;

/*
 * 支付接口抽象类
 *
 */
@Component
@Slf4j
public abstract class AbstractPaymentService implements IPaymentService {

    /**
   * 获取支付回调地址（简化版本，只使用 outTradeNo）
   * @param notifyUrl 基础回调地址
   * @param outTradeNo 外部订单号
   * @return 回调地址
   */
  protected String getPayNotifyUrl(String notifyUrl, String outTradeNo) {
    return notifyUrl + "/payCallback/" + getPayChannelCode() + "/" + outTradeNo;
  }

  /**
   * 获取支付回调地址
   * @return 回调地址
   */
  protected String getReturnUrl() {
    return "/pay/return/" + getPayChannelCode();
  }

  /**
   * 获取支付回调地址
   * @param payOrderId 支付单号
   * @return 回调地址
   */
  protected String getReturnUrl(String payOrderId) {
    return "/pay/return/" + getPayChannelCode() + "/" + payOrderId;
  }

  /**
   * 获取支付回调地址
   * @param payOrderId 支付单号
   * @return 回调地址
   */
  protected String getReturnUrlOnlyJump(String payOrderId) {
    return "/api/pay/return/" + getPayChannelCode() + "/ONLYJUMP_" + payOrderId;
  }

  /**
   * 订单分账（一般用作 如微信订单将在下单处做标记）
   *
   * @param request 统一支付请求
   */
  protected boolean isProfitSharingOrder(UnifyOrderReq request) {
    // 订单分账:自动或者手动， 将冻结商户资金。
    if (ProfitSharingModeEnum.AUTO.getCode().equals(request.getProfitSharingMode())
        || ProfitSharingModeEnum.MANUAL.getCode().equals(request.getProfitSharingMode())) {
      log.info("订单分账模式： {}", request.getProfitSharingMode());
      return true;
    }
    return false;
  }

  /**
   * 获取退款回调地址
   * @param notifyUrl 基础回调地址
   * @param outRefundNo 退款单号
   * @return 退款回调地址
   */
  protected String getRefundNotifyUrl(String notifyUrl, String outRefundNo) {
    return notifyUrl + "/refundCallback/" + getPayChannelCode() + "/" + outRefundNo;
  }

  /**
   * 获取退款回调地址（简化版本，只使用 outRefundNo）
   * @param notifyUrl 基础回调地址
   * @param outRefundNo 退款单号
   * @return 退款回调地址
   */
  protected String getRefundNotifyUrlSimple(String notifyUrl, String outRefundNo) {
    return notifyUrl + "/" + getPayChannelCode() + "/" + outRefundNo;
  }

  /**
   * 验证退款回调数据完整性
   * @param requestMap 回调数据
   * @return 是否有效
   */
  protected boolean validateRefundCallbackData(Map<String, Object> requestMap) {
    if (requestMap == null) {
      return false;
    }
    
    // 检查必要的退款字段
    String resultCode = (String) requestMap.get("resultCode");
    String refundNo = (String) requestMap.get("refundNo");
    String orderNo = (String) requestMap.get("orderNo");
    
    return resultCode != null && !resultCode.isEmpty() 
           && refundNo != null && !refundNo.isEmpty()
           && orderNo != null && !orderNo.isEmpty();
  }

  /**
   * 验证退款金额一致性
   * @param expectedAmount 期望退款金额
   * @param actualAmount 实际退款金额
   * @return 是否一致
   */
  protected boolean validateRefundAmount(BigDecimal expectedAmount, BigDecimal actualAmount) {
    if (expectedAmount == null || actualAmount == null) {
      return false;
    }
    
    // 允许0.01元的误差（处理微信支付分转元的精度问题）
    BigDecimal difference = expectedAmount.subtract(actualAmount).abs();
    return difference.compareTo(new BigDecimal("0.01")) <= 0;
  }

  /**
   * 判断退款是否成功
   * @param resultCode 退款结果码
   * @return 是否成功
   */
  protected boolean isRefundSuccess(String resultCode) {
    return "SUCCESS".equals(resultCode);
  }

  /**
   * 判断退款是否失败
   * @param resultCode 退款结果码
   * @return 是否失败
   */
  protected boolean isRefundFailed(String resultCode) {
    return "FAILED".equals(resultCode) || "CLOSED".equals(resultCode);
  }

  /**
   * 获取退款状态描述
   * @param resultCode 退款结果码
   * @return 状态描述
   */
  protected String getRefundStatusDescription(String resultCode) {
    if (isRefundSuccess(resultCode)) {
      return "退款成功";
    } else if (isRefundFailed(resultCode)) {
      return "退款失败";
    } else if ("PROCESSING".equals(resultCode)) {
      return "退款处理中";
    } else if ("ABNORMAL".equals(resultCode)) {
      return "退款异常";
    } else {
      return "未知状态";
    }
  }

  /**
   * 新的退款实现接口 - 默认实现
   */
  public AbstractRes refund(RefundUnifyReq request) throws Exception {
    throw new UnsupportedOperationException("子类必须实现 refund(RefundUnifyReq request) 方法");
  }

}
